﻿#region zh-CHS 2006 - 2007 DemoSoft 团队 | en 2006 - 2007 DemoSoft Team

//     NOTES
// ---------------
//
// This file is a part of the G.O.S.E(Game Online Server Engine) for .NET.
//
//                 2006-2007 DemoSoft Team
//
//
// First Version : by H.Q.Cai - mailto:caihuanqing@hotmail.com

/***************************************************************************
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU Lesser General Public License as published
 *   by the Free Software Foundation; either version 2.1 of the License, or
 *   (at your option) any later version.
 *
 ***************************************************************************/

#region zh-CHS 包含名字空间 | en Include namespace
using System;
using System.Text;
using System.Collections.Generic;
using Demo_G.O.S.E.ServerEngine.Util;
using Demo_G.O.S.E.ServerEngine.Network;
#endregion

namespace Demo_G.O.S.E.ServerEngine.Common
{
    /// <summary>
    /// 
    /// </summary>
    public struct Point2D : IPoint2D, IComparable, IComparable<Point2D>
    {
        #region zh-CHS 类常量 | en Class Constants
        public static readonly Point2D Zero = new Point2D( 0, 0 );
        #endregion

        #region zh-CHS 构造和初始化和清理 | en Constructors and Initializers and Dispose
        public Point2D( long x, long y )
        {
            m_X = x;
            m_Y = y;
        }

        public Point2D( IPoint2D point2D )
            : this( point2D.X, point2D.Y )
        {
        }
        #endregion

        #region zh-CHS 属性 | en Properties
        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private long m_X;
        #endregion
        [CommandProperty( AccessLevel.Counselor )]
        public long X
        {
            get { return m_X; }
            set { m_X = value; }
        }

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private long m_Y;
        #endregion
        [CommandProperty( AccessLevel.Counselor )]
        public long Y
        {
            get { return m_Y; }
            set { m_Y = value; }
        }
        #endregion

        #region zh-CHS 方法 | en Method
        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static Point2D Parse( string value )
        {
            int start = value.IndexOf( '(' );
            int end = value.IndexOf( ',', start + 1 );

            string param1 = value.Substring( start + 1, end - ( start + 1 ) ).Trim();

            start = end;
            end = value.IndexOf( ')', start + 1 );

            string param2 = value.Substring( start + 1, end - ( start + 1 ) ).Trim();

            return new Point2D( Convert.ToInt32( param1 ), Convert.ToInt32( param2 ) );
        }

        public static bool operator ==( Point2D l, Point2D r )
        {
            return l.m_X == r.X && l.Y == r.Y;
        }

        public static bool operator !=( Point2D l, Point2D r )
        {
            return l.m_X != r.X || l.Y != r.Y;
        }

        public static bool operator ==( Point2D l, IPoint2D r )
        {
            if ( Object.ReferenceEquals( r, null ) )
                return false;

            return l.m_X == r.X && l.Y == r.Y;
        }

        public static bool operator !=( Point2D l, IPoint2D r )
        {
            if ( Object.ReferenceEquals( r, null ) )
                return false;

            return l.m_X != r.X || l.Y != r.Y;
        }

        public static bool operator >( Point2D l, Point2D r )
        {
            return l.m_X > r.X && l.Y > r.Y;
        }

        public static bool operator >( Point2D l, Point3D r )
        {
            return l.m_X > r.X && l.Y > r.Y;
        }

        public static bool operator >( Point2D l, IPoint2D r )
        {
            if ( Object.ReferenceEquals( r, null ) )
                return false;

            return l.m_X > r.X && l.Y > r.Y;
        }

        public static bool operator <( Point2D l, Point2D r )
        {
            return l.m_X < r.X && l.Y < r.Y;
        }

        public static bool operator <( Point2D l, Point3D r )
        {
            return l.m_X < r.X && l.Y < r.Y;
        }

        public static bool operator <( Point2D l, IPoint2D r )
        {
            if ( Object.ReferenceEquals( r, null ) )
                return false;

            return l.m_X < r.X && l.Y < r.Y;
        }

        public static bool operator >=( Point2D l, Point2D r )
        {
            return l.m_X >= r.X && l.Y >= r.Y;
        }

        public static bool operator >=( Point2D l, Point3D r )
        {
            return l.m_X >= r.X && l.Y >= r.Y;
        }

        public static bool operator >=( Point2D l, IPoint2D r )
        {
            if ( Object.ReferenceEquals( r, null ) )
                return false;

            return l.m_X >= r.X && l.Y >= r.Y;
        }

        public static bool operator <=( Point2D l, Point2D r )
        {
            return l.m_X <= r.X && l.Y <= r.Y;
        }

        public static bool operator <=( Point2D l, Point3D r )
        {
            return l.m_X <= r.X && l.Y <= r.Y;
        }

        public static bool operator <=( Point2D l, IPoint2D r )
        {
            if ( Object.ReferenceEquals( r, null ) )
                return false;

            return l.m_X <= r.X && l.Y <= r.Y;
        }

        public override bool Equals( object o )
        {
            if ( o == null || !( o is IPoint2D ) ) return false;

            IPoint2D p = (IPoint2D)o;

            return m_X == p.X && m_Y == p.Y;
        }

        public override int GetHashCode()
        {
            return (int)( m_X ^ m_Y );
        }

        public override string ToString()
        {
            return String.Format( "({0}, {1})", m_X, m_Y );
        }

        public int CompareTo( Point2D other )
        {
            int v = ( m_X.CompareTo( other.X ) );

            if ( v == 0 )
                v = ( m_Y.CompareTo( other.Y ) );

            return v;
        }

        public int CompareTo( object other )
        {
            if ( other is Point2D )
                return this.CompareTo( (Point2D)other );
            else if ( other == null )
                return -1;

            throw new ArgumentException();
        }
        #endregion
    }
}
#endregion

